package com.cobla.struct.lineartable;

import com.cobla.struct.common.Const;
import lombok.Data;

/**
 * 线性表
 * @date 219/8/24
 * @author wt
 */
@Data
public class Sqlist {

    private int[] data;
    private int length;

    public Sqlist() {
        this.length = 0;
        this.data = new int[Const.MAXSIZE];
    }

    /**
     * 比较元素，返回 {@param x}应该插入的位置，这里默认数组是顺序的
     * @param x
     * @return
     */
    public int findElemBeforeInsert(int x){
        int i = 0;
        for (; i < this.length; i++) {
            if (x < this.data[i]) {
                return i;
            }
        }
        return i;
    }

    /**
     * 查找元素，找不到返回-1，默认数组乱序
     * @param x
     * @return
     */
    public int findElem(int x) {
        for (int i = 0; i < this.length; i++) {
            if (x == this.data[i]) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 插入元素，按元素大小插入
     * @param x
     */
    public void insertElem(int x) {
        int p, i;
        p = findElemBeforeInsert(x);
        for (i = this.length-1; i >= p; i--) {
            this.data[i+1] = this.data[i];
        }
        this.data[p] = x;
        ++this.length;
    }

    /**
     * 在 p 位置插入 e，如果 p 越界，返回 0，插入后，原位置及后面的元素全部后移一位，成功返回 1
     * @param p 插入位置
     * @param e 插入元素
     * @return 返回成功与否状态码
     */
    public int insertElem(int p, int e) {
        /* p 越界 */
        if (p >= this.length || p < 0) {
            return 0;
        }
        /* 数组最大限制 */
        if (this.length == Const.MAXSIZE) {
            return 0;
        }
        for (int i = this.length-1; i >= p; i--) {
            this.data[i + 1] = this.data[i];
        }
        this.data[p] = e;
        this.length++;
        return 1;
    }

    /**
     * 删除 p 位置的元素，返回被删除元素，或者返回null代表删除失败
     * @param p 删除位置
     * @return 是否成功
     */
    public Integer deleteElem(int p) {
        /* p 越界 */
        if (p < 0 || p >= this.length) {
            return null;
        }
        Integer e = this.data[p];
        for (int i = p; i < this.length; i++) {
            this.data[p] = this.data[p + 1];
        }
        return e;
    }

    /**
     * 返回指定位置的 p 的元素值，p 越界返回 null
     * @param p
     * @return
     */
    public Integer getElem(int p) {
        /* p 越界 */
        if (p < 0 || p >= this.length) {
            return null;
        }
        return this.data[p];
    }
}
